using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using System.IO.Ports;
using System.Text;
using System.Collections;

#if MINI
using SecretLabs.NETMF.Hardware.NetduinoMini;
#else
using SecretLabs.NETMF.Hardware.Netduino;
#endif

namespace codebase
{
    class DS1672RTC
    {
        private I2CDevice _i2c = new I2CDevice(new I2CDevice.Configuration(0x68, 400));

        public DS1672RTC(bool withCharger)
        {
            this.Init();
            if (withCharger) this.StartCharger();
        }

        private void Init()
        {
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];
            byte[] output = new byte[2];
            output[0] = 0x04;//select control register
            output[1] = 0x00;//set EOSC to 0 and start oscillator
            xActions[0] = I2CDevice.CreateWriteTransaction(output);
            _i2c.Execute(xActions, 100);
        }

        private void StartCharger()
        {
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];
            byte[] output = new byte[2];
            output[0] = 0x05;//select charger register
            output[1] = 0xAB;//set one diode, 4k resistor
            xActions[0] = I2CDevice.CreateWriteTransaction(output);
            _i2c.Execute(xActions, 100);
        }

        public long Read()
        {
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];
            byte[] input = new byte[4];
            byte[] output = new byte[1];
            output[0] = 0x00;//select 1st register
            xActions[0] = I2CDevice.CreateWriteTransaction(output);
            xActions[1] = I2CDevice.CreateReadTransaction(input);
            _i2c.Execute(xActions, 100);

            return ((long)input[3] << 24) | ((long)input[2] << 16) |
            ((long)input[1] << 8) | input[0];
        }

        public void Set(DateTime _DateTime)
        {
            long seconds = DateTimeToUnixTimestamp(_DateTime);

            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];

            byte[] output = new byte[5];
            output[0] = 0x00;//select 1st register
            output[1] = (byte)(seconds & 0xFF); ;//set register 0 LSB
            output[2] = (byte)((seconds >> 8) & 0xFF); ;//set register 1
            output[3] = (byte)((seconds >> 16) & 0xFF); ;//set register 2
            output[4] = (byte)((seconds >> 24) & 0xFF); ;//set register 3 MSB
            xActions[0] = I2CDevice.CreateWriteTransaction(output);

            _i2c.Execute(xActions, 100);
        }

        public DateTime UnixTimestampToDateTime(long _UnixTimeStamp)
        {
            return (new DateTime(1970, 1, 1, 0, 0, 0)).AddSeconds(_UnixTimeStamp);
        }

        public long DateTimeToUnixTimestamp(DateTime _DateTime)
        {
            TimeSpan _UnixTimeSpan = (_DateTime - new DateTime(1970, 1, 1, 0, 0, 0));
            long seconds = (_UnixTimeSpan.Days * 86400) +
            (_UnixTimeSpan.Hours * 3600) +
            (_UnixTimeSpan.Minutes * 60) +
            _UnixTimeSpan.Seconds;
            return seconds;

        }


    }
}
